package com.ben.tcptester.web.websocket;

import com.ben.tcptester.Entity.Server;
import com.ben.tcptester.bean.ws.WsBaseResponse;
import com.ben.tcptester.bean.ws.WsMsgType;
import com.ben.tcptester.tcpclient.netty.ServerRepository;
import com.ben.tcptester.util.JsonUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by Peter on 2017/6/15.
 */
public class MyTextWebSocketHandler extends TextWebSocketHandler {
    private static final Logger logger = LoggerFactory.getLogger(MyTextWebSocketHandler.class);

    private static final Map<String, WebSocketSession> users = new HashMap();

    // 接收到消息
    @Override
    public void handleTextMessage(WebSocketSession session, TextMessage message) {
        String sessionId = session.getId();
        String msg = new String(message.asBytes());
        logger.info("WS:::: 接收到消息" + sessionId + "------" + msg);
        sendMessageToAllUser(message);
    }

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        logger.info("WS:::: a WebSocket connected, sessionId=" + session.getId());
        users.put(session.getId(), session);

        WsBaseResponse message = new WsBaseResponse(WsMsgType.sessionId, session.getId());
        TextMessage textMessage = new TextMessage(JsonUtil.toJson(message));
        session.sendMessage(textMessage);
    }

    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        if (session.isOpen()) {
            session.close();
        }
        logger.info("WS:::: handleTransportError --> WebSocket connection manual closed, sessionId=" + session.getId());
        users.remove(session.getId());
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
        logger.info("WS:::: WebSocket connection closed, sessionId=" + session.getId());
        users.remove(session.getId());
    }

    /**
     * 给所有用户发送消息
     *
     * @param message
     */
    public static void sendMessageToAllUser(TextMessage message) {

        for (String key : users.keySet()) {
            WebSocketSession user = users.get(key);
            try {
                if (user.isOpen()) {
                    user.sendMessage(message);
                    logger.info("WS:::: 发送消息 to " + user.getId() + "--->>" + new String(message.asBytes()));
                }
            } catch (IOException e) {
                logger.error(e.getMessage(), e);
            }
        }
    }

    /**
     * 给所有用户发送消息
     *
     * @param message
     */
    public static void sendMessageUser(TextMessage message, String channelId) {
        try {
            Server server = ServerRepository.getByChannelId(channelId);
            if (server != null) {
                String key = server.getWsSessionId();
                WebSocketSession user = users.get(key);
                if (user.isOpen()) {
                    user.sendMessage(message);
                    logger.info("WS:::: 发送消息 to " + user.getId() + "--->>" + new String(message.asBytes()));
                } else {
                    logger.error("发送消息失败：因WsSession closed, sessionId=" + user.getId());
                }
            } else {
                logger.error("发送消息失败：因没有和该channel对应的Server, channelId=" + channelId);
            }
        } catch (IOException e) {
            logger.error(e.getMessage(), e);
        }
    }
}
